const fs = require("fs");
var Xray = require('x-ray');
const { requestTranslate } = require("../apiFoxFlutterGenerate/baidu/translation");
const { lowerCamelCase } = require("../apiFoxFlutterGenerate/tool/lowerCamelCase");
const path = require('path');

var x = Xray()
var isPageRequest = true
var modelName = ''
var funcNameStr = ''
var methodsName = ''
var returnFuturnName = ''
var paramsGroups = []
var actionStringName = ''
var actionTitle = ''

async function analysisHtmlFile(filePath, _modelName, complete) {
    isPageRequest = false
    if (_modelName != undefined && _modelName.length > 0) {
        modelName = _modelName

    } else {
        modelName = undefined
    }
    fs.readFile(filePath, "utf-8", async function (error, data) {
        if (error) return

        let funcNameParamsStr = await analysisFileContent(data)
        _writeFile(funcNameParamsStr)
        if (complete != undefined) {
            complete()
        }
    });
}

async function analysisContent(data, _modelName) {
    isPageRequest = false
    if (_modelName != undefined && _modelName.length > 0) {
        modelName = _modelName

    } else {
        modelName = 'bool'
    }

    return analysisFileContent(data)
}

async function analysisFileContent(data) {


    var response = await x(data, '.sl-text-sm')
    var objectKeyVal = await x(data, '.object-key-val')


    var method = await x(data, '.request-method-icon')

    var url = await x(data, '.pui-g-ui-kit-copyable-text-kit-index-copyable')
    actionTitle = await x(data, '.group-title.mb-0.text-base')

    var id = await x(data, '.text-sm')
    console.log('id ' + id);
    var transRes = await requestTranslate(actionTitle)
    methodsName = transRes.data.trans_result[0].dst
    methodsName = lowerCamelCase(methodsName)
    methodsName = methodsName.replace(/[^\d|a-z|A-Z]/g, '')
    // transName = transName.replace(/\s*/g, "")

    methodsName = 'request' + methodsName

    url = '\'' + url + '\''
    methodsName = methodsName.replace('/', 'Or')

    var list = []

    var paramsCount = 4;
    var fKeys = await x(data, '#f参数keys')

    // var getParamsName
    // if (url.indexOf('{') > 0) {
    //     getParamsName = url.split('{')[1]
    //     getParamsName = getParamsName.split('}')[0]
    // }
    var hasFKeys = false
    if (fKeys.length != 0) {
        hasFKeys = true
    }

    var pathParams = []
    var bodyParams = []
    var fParams = []
    var queryParams = []
    paramsGroups = []

    var re = await x(data, ['.ui-card-small'])
    console.log(re);
    var cards = await x(data, x('.ui-card.ui-card-bordered.ui-card-small', [
        {
            title: '.ui-card-head-title',
            values: x('.sl-max-w-full', [{
                name: await x('.pui-pages-api-api-manage-http-http-api-http-api-view-index-property-name')

            }]),
            names: ['.pui-pages-api-api-manage-http-http-api-http-api-view-index-property-name'],
            types: ['.sl-text-muted-big.sl-type span'],
            requireds: ['.index_required__SSXQb,.index_optional__O33wK'],
            desces: ['.pui-g-ui-kit-markdown-preview-index-container p']
        }
    ]))
    console.log(cards);

    for (let index = 0; index < cards.length; index++) {
        const element = cards[index];
        const title = element.title;
        const array = element.names;
        // if (title.indexOf('Header') < 0) {
        //     for (let index = 0; index < array.length; index++) {
        //         const actionName = array[index]
        //         console.log(actionName);
        //         if (actionName != 'f') {
        //             paramsGroups.push([actionName, element.types[index], element.requireds[index], element.desces[index]]);
        //             if (title.indexOf('Path') < 0) { bodyParams = paramsGroups; }
        //         }
        //     }

        // }

        if (title.indexOf('Path') >= 0) {
            console.log(array);
            for (let index = 0; index < array.length; index++) {
                const actionName = array[index]
                paramsGroups.push([actionName, element.types[index], element.requireds[index], element.desces[index]]);
                pathParams.push([actionName, element.types[index], element.requireds[index], element.desces[index]]);
            }
        } else if (title.indexOf('Body') >= 0) {
            for (let index = 0; index < array.length; index++) {
                const actionName = array[index]
                paramsGroups.push([actionName, element.types[index], element.requireds[index], element.desces[index]]);
                bodyParams.push([actionName, element.types[index], element.requireds[index], element.desces[index]]);
            }
        } else if (title.indexOf('Query') >= 0) {
            for (let index = 0; index < array.length; index++) {
                const actionName = array[index]
                if (actionName != 'f') {
                    paramsGroups.push([actionName, element.types[index], element.requireds[index], element.desces[index]]);
                    queryParams.push([actionName, element.types[index], element.requireds[index], element.desces[index]]);
                }
            }
        }
    }

    if (method == 'GET') {
        if (hasFKeys) {
            list = await x(data, '.markdown-body', ['td']) ?? []
            var h4List = await x(data, '.markdown-body', ['h4'])
            var count0 = h4List.length
            var count1 = await x(data, '.markdown-body table tr', ['th'])
            paramsCount = count1.length / count0
            var first = list[0]
            var secondIndex = list.indexOf(first, 2)
            list = list.slice(0, secondIndex);
        }
    }

    for (let index = 0; index < list.length; index++) {
        const element = list[index];
        if (element == 'platform全') {
            list.splice(index, 5)
        }
    }

    for (let index = 0; index < list.length; index++) {
        const element = list[index];
        if (element == 'path') {
            pathParams.push(list.splice(index - 1, 5))
        }

    }



    for (let index = 0; index < list.length; index++) {
        const element = list[index];
        if (element.indexOf('成功') >= 0) {
            list = list.slice(index + 4, list.length)
            break;
        }
    }

    if (hasFKeys) {
        var arr = list;
        var groupSize = paramsCount <= 4 ? 4 : paramsCount;
        var groups = arr.reduce(function (result, value, index, array) {
            if (index % groupSize === 0) {
                result.push(array.slice(index, index + groupSize));
            }
            return result;
        }, []);
        fParams = groups;

        paramsGroups = pathParams.concat(groups);
        paramsGroups = paramsGroups.concat(queryParams);
    }else{

    }
    console.log('pathParams');
    console.log(pathParams);
    console.log(paramsGroups);

    // if (getParamsName != undefined) {
    //     url = url.split('{')[0]
    //     url = url.substring(url.length - 1, 1)
    //     url = "'" + url
    //     // url +=  "'"
    //     url += '/$' + getParamsName + '\''
    //     queryList = fKeys
    // }

    var reg = /\{(\w+)\}/g;
    url = url.replace(reg, (matched, cap1, location, groups) => {
        return '$' + lowerCamelCase(cap1);
    })

    var classT = '<' + modelName + '>'
    if (modelName == undefined) {
        classT = ''
    }

    

    // for (let index = 0; index < pathParams.length; index++) {
    //     const element = pathParams[index];
    //     paramsGroups.push(element)
    // }

    var funcNameParamsStr = '/// ' + actionTitle + " id: " + id + '\n'
    for (let index = 0; index < paramsGroups.length; index++) {
        const element = paramsGroups[index];
        funcNameParamsStr += paramsDesc(element) + '\n'
    }

    funcNameParamsStr += 'static '
    funcNameStr = ''
    returnFuturnName = 'Future' + classT + ' '
    funcNameStr += returnFuturnName + methodsName + '(\n{'
    for (let index = 0; index < paramsGroups.length; index++) {
        const element = paramsGroups[index];
        funcNameStr += paramsString(element)
    }
    if (isPageRequest) {
        funcNameStr += 'PageMetaCallback? metaCallback,'
    }
    funcNameStr += '}) {\n'

    funcNameParamsStr += funcNameStr


    funcNameParamsStr += 'return RequestModel.request' + classT + '(\n'
    funcNameParamsStr += 'HttpMethod.'
    funcNameParamsStr += method + ','
    funcNameParamsStr += url + ','


    var jsonModel = modelName + '()'
    if (modelName != null) {
        if (modelName == 'bool') {
            jsonModel = 'true'
        } else {

        }
    }
    if (jsonModel.indexOf('List') == 0) {
        jsonModel = jsonModel.substring(4, jsonModel.length - 2)
        jsonModel = jsonModel.substring(1, jsonModel.length)
        jsonModel = jsonModel.substring(0, jsonModel.length - 1)
        jsonModel = '[' + jsonModel + '()]'
    }
    jsonModel = 'jsonModel: ' + jsonModel
    if (modelName == null || modelName == undefined) {

    } else {
        funcNameParamsStr += jsonModel + ','
    }

    var pageInts = []



    // for (let index = pageInts.length - 1; index >= 0; index--) {
    //     const element = pageInts[index];
    //     groups.splice(element, 1)
    // }

    // if (queryParams.length > 0) {
    //     funcNameParamsStr += 'queryParameters: {'
    //     for (let index = 0; index < queryParams.length; index++) {
    //         const element = queryParams[index];
    //         funcNameParamsStr += paramsRequest(element)
    //     }
    //     // if (getParamsName != undefined) {
    //     //     funcNameParamsStr += "'" + getParamsName + "': " + getParamsName + ','
    //     // }
    //     funcNameParamsStr += '},'
    // }

    if (queryParams.length > 0) {
        funcNameParamsStr += genParams('queryParameters', queryParams)
    }

    if (fParams.length > 0) {
        funcNameParamsStr += genParams('fArg', fParams)
    }

    if (bodyParams.length > 0) {
        funcNameParamsStr += genParams('body', bodyParams)
    }


    funcNameParamsStr += ');\n}\n'
    console.log(funcNameParamsStr);
    return funcNameParamsStr
}

function viewModelFunc() {
    var viewModelFuncStr = 'final '
    actionStringName = methodsName + 'ActionName'
    viewModelFuncStr += actionStringName
    viewModelFuncStr += "='" + actionStringName + "';\n"
    viewModelFuncStr += returnFuturnName + "_" + methodsName + "WithAction(RequestAction action) {\n"
    viewModelFuncStr += 'return Api.' + methodsName + '(\n'
    for (let index = 0; index < paramsGroups.length; index++) {
        const element = paramsGroups[index];
        var name = element[0]
        name = lowerCamelCase(name)

        var str = name + ": action.argMap?['" + name + "'],"
        viewModelFuncStr += str
    }
    if (isPageRequest) {
        viewModelFuncStr += "metaCallback: action.argMap?['metaCallback'],"
    }
    viewModelFuncStr += ');}\n\n'
    viewModelFuncStr += '/// ' + actionTitle + '\n'
    viewModelFuncStr += returnFuturnName + methodsName + '(\n{'
    for (let index = 0; index < paramsGroups.length; index++) {
        const element = paramsGroups[index];
        viewModelFuncStr += paramsString(element)
    }
    if (isPageRequest) {
        viewModelFuncStr += 'PageMetaCallback? metaCallback,'
    }
    viewModelFuncStr += '}) {\n'
    viewModelFuncStr += 'return dispatchAction<' + modelName + '>(RequestAction(' + actionStringName + ', argMap: {'
    for (let index = 0; index < paramsGroups.length; index++) {
        const element = paramsGroups[index];
        var name = element[0]
        name = lowerCamelCase(name)

        var str = "'" + name + "'" + ": " + name + ","
        viewModelFuncStr += str
    }
    if (isPageRequest) {
        viewModelFuncStr += "'metaCallback': metaCallback,"
    }
    viewModelFuncStr += '}));\n}'
    return viewModelFuncStr
}

function pageLoad() {
    var str = '@override\n'
    str += returnFuturnName + 'load(int pageIndex, int pageSize) {\n'
    str += 'return ' + methodsName + '(page: pageIndex, pageSize: pageSize);'
    str += "}"

    return str
}



function genParams(name, groups) {
    var funcNameParamsStr = ''
    funcNameParamsStr += name + ': {'
    for (let index = 0; index < groups.length; index++) {
        const element = groups[index];
        funcNameParamsStr += paramsRequest(element)

    }
    funcNameParamsStr += '},'
    return funcNameParamsStr
}


function paramsRequest(list) {
    var name = list[0]
    var lowerCamelCaseName = lowerCamelCase(name)
    return '\'' + name + '\': ' + lowerCamelCaseName + ','
}

function paramsDesc(list) {
    var name = list[0]
    name = lowerCamelCase(name)

    var desc = list[list.length - 1]
    return '/// [' + name + '] ' + desc //+ ' 是否必填:' + list[2]
}

function paramsString(list) {
    var name = list[0]
    name = lowerCamelCase(name)
    var type = dartClassName(list[1])
    var isRequire = (list[list.length - 2] === '是' || list[list.length - 2] === '必需')

    /// int pageIndex = 1,
    /// int pageSize = 20,
    if (name === 'page') {
        isPageRequest = true
        return 'int? page,'
    } else if (name === 'pageSize') {
        isPageRequest = true
        return 'int? pageSize,'
    }

    if (isRequire) {
        return 'required ' + type + ' ' + name + ','
    }
    return type + '? ' + name + ','

}

function dartClassName(name) {
    switch (name) {
        case 'string':
            return 'String'

        default:
            return name
    }
}

module.exports = {
    analysisHtmlFile: analysisHtmlFile,
    analysisFileContent: analysisFileContent,
    analysisContent: analysisContent,
    viewModelFunc: viewModelFunc,
    pageLoad: pageLoad,
}

function _writeFile(fileContent) {
    let _direct = "../apiFoxFlutterGenerate/"
    let _fileName = _direct + 'api.dart'

    let file = path.resolve(__dirname, _fileName)
    let resContent = 'class ClassName {'
    resContent += fileContent
    resContent += '}'
    resContent += "class PageMetaCallback {}class HttpMethod {static var GET;static var POST;static var PUT;static"
        + " var DELETE;}class RequestModel {static Future<T> request<T>(get, String s,{T? jsonModel, "
        + " Map<String, Object?>? fArg,Map<String, Object?>? queryParameters,Map<String, String?>? body}) {return Future.delayed(Duration.zero);}}"

    fs.writeFile(file, resContent, { encoding: 'utf8' }, err => { })
}